package com.eastfair.file.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.file.service.util.FileTool;
import com.eastfair.file.vo.FileVO;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

/**
 * 文件服务
 */
public interface FileService {

    String[] WHITE_LIST = {
            ".jpeg",
            ".jpg",
            ".png",
            ".gif",
            ".dwg",
            ".docx",
            ".doc",
            ".xls",
            ".xlsx",
            ".pdf",
            ".rar",
            ".zip",
            ".bmp"
    };

    /**
     * 本地文件上传
     *
     * @param multipartFile the multipart file
     * @param bucketName    the bucket name
     * @return file vo
     * @throws Exception the exception
     */
    FileVO uploadFile(MultipartFile multipartFile, String bucketName) throws Exception;

    /**
     * 文件上传
     *
     * @param multipartFile the multipart file
     * @param bucketName    the bucket name
     * @param isMobile      the is mobile
     * @return the file vo
     * @throws Exception the exception
     */
    FileVO uploadFile(MultipartFile multipartFile, String bucketName, String isMobile) throws Exception;

    /**
     * 用扩展名白名单校验扩展名
     *
     * @param subFix the subfix
     */
    static void verifySubFix(String subFix) {
        if (StrUtil.isBlank(subFix)) {
            throw BizException.wrap(1001, "文件扩展名不存在");
        }
        subFix = subFix.toLowerCase(Locale.ENGLISH);
        List<String> whiteList = new ArrayList<>();
        Collections.addAll(whiteList, WHITE_LIST);
        if (!whiteList.contains(subFix)) {
            throw BizException.wrap(1004, subFix + " 扩展名非法");
        }
    }

    /**
     * 验证文件格式与扩展名是否一致
     *
     * @param subFix the sub fix
     * @param file   the file
     * @throws IOException the io exception
     */
    static void verifyFileRowSubFix(String subFix, MultipartFile file) throws IOException {
        if (StrUtil.isBlank(subFix)) {
            throw BizException.wrap(1001, "文件扩展名不存在");
        }
        try (InputStream inputStream = file.getInputStream()) {
            // 验证扩展名与文件格式是否一致
            String suffix = subFix.substring(subFix.indexOf(".") + 1);
            byte[] buffer = new byte[16];
            inputStream.read(buffer, 0, buffer.length);

            // 获取文件头编码
            String fileTypeCode = FileTool.getRowFileTypeCode(buffer);
            // 判断是否一致
            boolean isSame =  FileTool.verifyFileRowSubFix(suffix, fileTypeCode);
            if (!isSame) {
                // 获取文件的原始类型
                List<String> possibleFileTypeList = FileTool.getRowFileType(fileTypeCode);
                if (!possibleFileTypeList.isEmpty()) {
                    String possibleFileTypeString = CollectionUtil.join(possibleFileTypeList, "，");
                    throw BizException.wrap(1005, "文件格式与扩展名不符，文件原本格式为 " + possibleFileTypeString);
                }
                throw BizException.wrap(1005, "文件格式与扩展名不符");
            }
        }
    }
}
